import { createClient } from 'redis';
import dotenv from 'dotenv';
import logger from './logger.js';

dotenv.config();

// 创建Redis客户端
const redisClient = createClient({
  url: process.env.REDIS_URL || `redis://${process.env.REDIS_HOST || 'localhost'}:${process.env.REDIS_PORT || 6379}`
});

// 错误处理
redisClient.on('error', (err) => {
  logger.error('Redis客户端错误:');
});

// 连接Redis
(async () => {
  try {
    await redisClient.connect();
    logger.info('成功连接到Redis');
  } catch (err) {
    logger.error('Redis连接错误:');
  }
})();

// 缓存工具函数
const cache = {
  // 设置缓存
  async set(key, value, expireTime = 3600) {
    try {
      if (typeof value === 'object') {
        value = JSON.stringify(value);
      }
      await redisClient.set(key, value, { EX: expireTime });
      logger.info(`设置缓存: ${key}，过期时间: ${expireTime}秒`);
      return true;
    } catch (err) {
      logger.error(`设置缓存失败: ${key}`, err.stack);
      return false;
    }
  },

  // 获取缓存
  async get(key) {
    try {
      const value = await redisClient.get(key);
      if (value) {
        logger.info(`获取缓存: ${key}`);
        // 尝试解析为JSON
        try {
          return JSON.parse(value);
        } catch (e) {
          return value;
        }
      }
      return null;
    } catch (err) {
      logger.error(`获取缓存失败: ${key}`, err.stack);
      return null;
    }
  },

  // 删除缓存
  async del(key) {
    try {
      await redisClient.del(key);
      logger.info(`删除缓存: ${key}`);
      return true;
    } catch (err) {
      logger.error(`删除缓存失败: ${key}`, err.stack);
      return false;
    }
  },

  // 清除所有缓存（谨慎使用）
  async flush() {
    try {
      await redisClient.flushAll();
      logger.info('清除所有缓存');
      return true;
    } catch (err) {
      logger.error('清除缓存失败', err.stack);
      return false;
    }
  },

  // 获取缓存中所有的键值对
  async getAll(prefix = '',json_or_text=true) {
    try {
      logger.info('获取所有缓存键值对');
      const keys = await redisClient.keys(`${prefix}*`);
      const keyValuePairs = [];
      for (const key of keys) {
        const value = await redisClient.get(key);
        // 尝试解析为JSON
        try {
          if(json_or_text){
            keyValuePairs.push({ key, value: JSON.parse(value) });
          }else{
            keyValuePairs.push(`${key}:${value}`);
          }
        } catch (e) {
          if(json_or_text){
            keyValuePairs.push(`${key}:${value}`);
          }else{
            keyValuePairs.push({ key, value });
          }
        } 
      }
      return keyValuePairs;
    } catch (err) {
      logger.error('获取所有缓存键值对失败', err.stack);
      return [];
    }
  },


  // 模糊查询缓存键
  async search(pattern) {
    try {
      logger.info(`模糊查询缓存，模式: ${pattern}`);
      const keys = [];
      let cursor = '0';
      
      do {
        const scanResult = await redisClient.scan(cursor, { MATCH: pattern, COUNT: 100 });
        cursor = scanResult.cursor;
        keys.push(...scanResult.keys);
      } while (cursor !== '0');
      
      logger.info(`找到 ${keys.length} 个匹配的缓存键`);
      return keys;
    } catch (err) {
      logger.error(`模糊查询缓存失败: ${pattern}`, err.stack);
      return [];
    }
  },

  // 执行Lua脚本
  async eval(script, numKeys, ...args) {
    try {
      logger.info(`执行Lua脚本`);
      return await redisClient.eval(script, {
        keys: args.slice(0, numKeys),
        arguments: args.slice(numKeys)
      });
    } catch (err) {
      logger.error(`执行Lua脚本失败`, err.stack);
      throw err;
    }
  }
};

// 导出redisClient以供需要直接访问底层客户端的场景使用
export { redisClient };
export default cache;